home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / basic / _olist.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  6.5 KB  |  387 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _olist.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. #include <LEDA/impl/olist.h>
  16. #include <ctype.h>
  17.  
  18. #define SWAP(a,b) { register obj_link* x = *a; *a = *b; *b = x; }
  19.  
  20. #define MIN_D 16 
  21.  
  22. //------------------------------------------------------------------------------
  23. // Members of class obj_list
  24. //------------------------------------------------------------------------------
  25.  
  26. obj_list::obj_list()      
  27. { h = nil; 
  28.   t = nil;
  29.   count = 0;
  30. }
  31.  
  32. void obj_list::clear()
  33. { h = nil;
  34.   t = nil;
  35.   count = 0;
  36.  }
  37.  
  38.  
  39. obj_link* obj_list::get_item(int i) const
  40. { obj_link* p = h;
  41.   while ( p && i--) p = p->succ_link; 
  42.   return p;
  43. }
  44.  
  45. obj_link* obj_list::succ(obj_link* p, int i)  const
  46. { while ( p && i--) p = p->succ_link; 
  47.   return p;
  48. }
  49.  
  50. obj_link* obj_list::pred(obj_link* p, int i) const
  51. { while ( p && i--) p = p->pred_link; 
  52.   return p;
  53. }
  54.  
  55.  
  56. int obj_list::rank(obj_link* x)   const   /* rank by linear search */
  57. { obj_link* p = h;
  58.   int r = 1;
  59.   while ( p && p != x) 
  60.   { p = p->succ_link; 
  61.     r++;
  62.    }
  63.   return (p) ? r : 0;
  64.  
  65.  
  66. obj_link* obj_list::insert(obj_link* n, obj_link* l, int dir) 
  67.   if (dir==0) //insert after l
  68.     return insert(n,l);
  69.   else //insert before l
  70.     { obj_link* p=l->pred_link;
  71.       n->pred_link = p;
  72.       n->succ_link = l;
  73.       l->pred_link = n;
  74.       if (l==h) h=n;
  75.       else p->succ_link = n;
  76.       count++;
  77.       return n;
  78.     }
  79. }
  80.  
  81.  
  82. void obj_list::conc(obj_list& l)
  83. { if (t) { t->succ_link = l.h;
  84.           if (l.h) { l.h->pred_link = t; t = l.t; } }
  85.    else { h = l.h; t = l.t; }
  86.  count = count+l.count;
  87.  l.h = l.t = 0;
  88.  l.count = 0;
  89. }
  90.  
  91.  
  92. void obj_list::split(obj_link* p, obj_list& l1, obj_list& l2)
  93.   l1.clear();
  94.   l2.clear();
  95.  
  96.   if (p==nil)    // l1 = empty,  l2 = l, l = empty;
  97.   { l2.h = h;
  98.     l2.t = t;
  99.     l2.count = count;
  100.     h = t = 0;
  101.     count = 0;
  102.     return;
  103.    }
  104.  
  105.   if (h == 0) return;   /* empty list */
  106.  
  107.  
  108.   if (p->pred_link)
  109.   { l1.h = h;
  110.     l1.t = p->pred_link;
  111.     p->pred_link->succ_link = 0;
  112.    }
  113.  
  114.   p->pred_link = 0;
  115.   l2.h = p;
  116.   l2.t = t;
  117.  
  118.  
  119.   // have to set counters
  120.   // "count the smaller half" gives amortized n log n  bound
  121.  
  122.   obj_link* l = l1.h;
  123.   obj_link* r = l2.h;
  124.   int    c = 0;
  125.  
  126.   while (l && r)
  127.   { l = l->succ_link;
  128.     r = r->succ_link;
  129.     c++;
  130.    }
  131.  
  132.   if (l==0)   // left end reached first
  133.   { l1.count = c;
  134.     l2.count = count - l1.count;
  135.    }
  136.  
  137.   else
  138.   { l2.count = c;
  139.     l1.count = count - l2.count;
  140.    }
  141.  
  142.   /* make original list empty */
  143.   
  144.   h = t = 0;
  145.   count = 0;
  146.  
  147. }
  148.  
  149.  
  150. void obj_list::del(obj_link* x)
  151.   if (x==h)  
  152.     pop();
  153.   else
  154.     if (x==t)  
  155.        Pop();
  156.     else
  157.        { obj_link*  p = x->pred_link;
  158.          obj_link*  s = x->succ_link;
  159.          p->succ_link = s;
  160.          s->pred_link = p;
  161.          count--;
  162.         }
  163. }
  164.  
  165.  
  166. obj_link* obj_list::max(CMP_ITEM f) const
  167. { if (h==0) return 0;
  168.   obj_link* m=h;
  169.   obj_link* p=m->succ_link;
  170.  
  171.      while (p)
  172.      { if (f(p,m) > 0) m=p;
  173.        p=p->succ_link;
  174.       }
  175.  
  176.   return m;
  177. }
  178.  
  179. obj_link* obj_list::min(CMP_ITEM f) const
  180. { if (h==0) return 0;
  181.   obj_link* m=h;
  182.   obj_link* p=m->succ_link;
  183.  
  184.      while (p)
  185.      { if (f(p,m) < 0) m=p;
  186.        p=p->succ_link;
  187.      }
  188.  
  189.   return m;
  190. }
  191.  
  192.  
  193. void obj_list::apply(APP_ITEM apply)
  194. { register obj_link* p = h;
  195.   while (p)
  196.   { apply(p);
  197.     p = p->succ_link;
  198.    }
  199. }
  200.  
  201. void obj_list::permute()
  202.   obj_link** A = new obj_link*[count+2];
  203.   obj_link* x = h;
  204.   int j;
  205.  
  206.   A[0] = A[count+1] = 0;
  207.  
  208.   for(j=1; j <= count; j++)
  209.   { A[j] = x;
  210.     x = x->succ_link;
  211.    }
  212.  
  213.   for(j=1; j<count; j++)  
  214.   { int r = random(j,count);
  215.     x = A[j];
  216.     A[j] = A[r];
  217.     A[r] = x;
  218.    }
  219.  
  220.   for(j=1; j<=count; j++) 
  221.   { A[j]->succ_link = A[j+1];
  222.     A[j]->pred_link = A[j-1];
  223.    }
  224.  
  225.   h = A[1];
  226.   t = A[count];
  227.   
  228.   delete A;
  229. }
  230.         
  231.  
  232. void obj_list::bucket_sort(int i, int j, ORD_ITEM ord)
  233.   int n = j-i+1;
  234.  
  235.   register obj_link** bucket= new obj_link*[n+1];
  236.   register obj_link** stop = bucket + n;
  237.   register obj_link** p;
  238.  
  239.   register obj_link* q;
  240.   register obj_link* x;
  241.  
  242.   for(p=bucket;p<=stop;p++)  *p = 0;
  243.  
  244.   while (h) 
  245.   { x = h; 
  246.     h = h->succ_link;
  247.     int k = ord(x);
  248.     if (k >= i && k <= j) 
  249.      { p = bucket+k-i;
  250.        x->succ_link = *p;
  251.        if (*p) (*p)->pred_link = x;
  252.        *p = x;
  253.       }
  254.     else 
  255.        error_handler(4,"bucket_sort: value out of range") ;
  256.    }
  257.  
  258.  for(p=bucket; *p==0 && p<stop; p++);
  259.   
  260.  h = *p;
  261.  
  262.  if (h) 
  263.  { for(q=h;q->succ_link; q = q->succ_link);
  264.    h->pred_link = 0;
  265.    p++;
  266.   }
  267.  
  268.  while(p<stop) 
  269.  { if (*p)
  270.    { q->succ_link = *p;
  271.      (*p)->pred_link = q;
  272.      while(q->succ_link) q = q->succ_link;
  273.     }
  274.    p++;
  275.   }
  276.  
  277.  t = q;
  278.  
  279.  delete bucket;
  280. }
  281.  
  282.         
  283. void obj_list::quick_sort(obj_link** l, obj_link** r, CMP_ITEM usr_cmp)
  284. { // use parameter usr_cmp
  285.  
  286.   register obj_link** i = l+(r-l)/2; //random()%(r-l);
  287.   register obj_link** k;
  288.  
  289.   if (usr_cmp((*i),(*r))>0) SWAP(i,r);
  290.  
  291.   SWAP(l,i);
  292.  
  293.   obj_link* s = (*l);
  294.  
  295.   i = l;
  296.   k = r;
  297.  
  298.   for(;;)
  299.   { while (usr_cmp((*(++i)),s)<0);
  300.     while (usr_cmp((*(--k)),s)>0);
  301.     if (i<k) SWAP(i,k) else break;
  302.    }
  303.  
  304.   SWAP(l,k);
  305.  
  306.   if (k > l+MIN_D) quick_sort(l,k-1,usr_cmp);
  307.   if (r > k+MIN_D) quick_sort(k+1,r,usr_cmp);
  308. }
  309.         
  310.  
  311.  
  312. void obj_list::insertion_sort(obj_link** l, obj_link** r, obj_link** min_stop, 
  313.                                CMP_ITEM usr_cmp)
  314. {
  315.   register obj_link** min=l;
  316.   register obj_link** run;
  317.   register obj_link** p;
  318.   register obj_link** q;
  319.  
  320.   for (run = l+1; run <= min_stop; run++)
  321.       if (usr_cmp((*run),(*min)) < 0) min = run;
  322.  
  323.   SWAP(min,l);
  324.  
  325.   if (r == l+1) return; 
  326.  
  327.   for(run=l+2; run <= r; run++)
  328.   { for (min = run-1; usr_cmp((*run),(*min)) < 0; min--);
  329.     min++;
  330.     if (run != min) 
  331.     { obj_link* save = *run;
  332.       for(p=run, q = run-1; p > min; p--,q--) *p = *q;
  333.       *min = save;
  334.      }
  335.    }
  336. }
  337.  
  338.  
  339.  
  340. void obj_list::sort(CMP_ITEM f)
  341.   if (count<=1) return;    // nothing to sort
  342.  
  343.   obj_link** A = new obj_link*[count+2];
  344.  
  345.   register obj_link*  loc = h;
  346.   register obj_link** p;
  347.   register obj_link** stop = A+count+1;
  348.  
  349.   obj_link** left  = A+1;
  350.   obj_link** right = A+count;
  351.   obj_link** min_stop = left + MIN_D;
  352.  
  353.   if (min_stop > right) min_stop = right;
  354.  
  355. min_stop = right;
  356.  
  357.   for(p=A+1; p<stop; p++)
  358.   { *p = loc;
  359.     loc = loc->succ_link;
  360.    }
  361.  
  362.  
  363.    quick_sort(left,right,f);
  364.    insertion_sort(left,right,min_stop,f);
  365.  
  366.   *A = *stop = 0;
  367.  
  368.   for (p=A+1;p<stop;p++) 
  369.   { (*p)->succ_link = *(p+1);
  370.     (*p)->pred_link = *(p-1);
  371.    }
  372.  
  373.   h = A[1];
  374.   t = A[count];
  375.  
  376.   delete A;
  377. }
  378.  
  379.